from marshmallow import Schema, fields, validate, ValidationError, pre_load
from enums.AppEnum import AppEnum
from models import App, UserAnswer  # 假设有这些模型
from common.BaseResponse import BaseResponse
from common.ApiResponse import ApiResponse
from common.ErrorCode import ErrorCode

# 预定义错误
param_error = BaseResponse.from_error_code(ErrorCode.PARAMS_ERROR)


def validate_userAnswer(data:UserAnswer,add:bool ):
    if data == None:
        print("UserAnswer is None")
        baseResponse = BaseResponse.from_error_code(ErrorCode.PARAMS_ERROR)
        return ApiResponse.error_from_baseResponse(baseResponse=baseResponse,data="UserAnswer is None")
    appId = data.appId
    id = data.id
    if add:
        if appId == None:
            print("AppId is None")
            baseResponse = BaseResponse.from_error_code(ErrorCode.PARAMS_ERROR)
            return ApiResponse.error_from_baseResponse(baseResponse=baseResponse, data="AppId is None")
        if id == None:
            print("id is None")
            baseResponse = BaseResponse.from_error_code(ErrorCode.PARAMS_ERROR)
            return ApiResponse.error_from_baseResponse(baseResponse=baseResponse, data="id is None")
    if appId is not None:
        app = App.query.filter_by(id=appId).first()
        if app == None:
            print("App不存在！")
            baseResponse = BaseResponse.from_error_code(ErrorCode.PARAMS_ERROR)
            return ApiResponse.error_from_baseResponse(baseResponse=baseResponse, data="app is None")


def validate_appId(data, **kwargs):
    try:
        app_id = int(data.get('appId'))
    except ValueError as err:
        print(f"appId有误: {err}")
        return ApiResponse.error_from_baseResponse(
            baseResponse=param_error,
            data="appId非法，应输入整数！"
        )
    app = App.query.get(app_id)
    if app is None:
        print("应用不存在，校验失败")
        return ApiResponse.error_from_baseResponse(
            baseResponse=param_error,
            data="请重新检查选择的应用"
        )


class UserAnswerAddRequest(Schema):
    id = fields.Int(
        required=False,
        allow_none=True,
        validate=validate.Range(min=1, error="ID必须大于0")
    )
    appId = fields.Int(
        required=True,
        allow_none=False,
        validate=validate.Range(min=1, error="应用ID必须大于0")
    )
    choices = fields.List(
        fields.String(),
        required=True,
        allow_none=False,
        validate=validate.Length(min=1, error="用户答案至少需要包含一个选项")
    )


class UserAnswerEditRequest(Schema):
    id = fields.Int(
        required=True,
        allow_none=True,
        validate=validate.Range(min=1, error="ID必须大于0")
    )
    appId = fields.Int(
        required=True,
        allow_none=False,
        validate=validate.Range(min=1, error="应用ID必须大于0")
    )
    choices = fields.List(
        fields.String(),
        required=True,
        allow_none=False,
        validate=validate.Length(min=1, error="用户答案至少需要包含一个选项")
    )


class UserAnswerUpdateRequest(Schema):
    id = fields.Int(
        required=True,
        allow_none=False,
        validate=validate.Range(min=1, error="ID必须大于0")
    )
    appId = fields.Int(
        required=True,
        allow_none=False,
        validate=validate.Range(min=1, error="应用ID必须大于0")
    )
    choices = fields.List(
        fields.String(),
        required=True,
        allow_none=False,
        validate=validate.Length(min=1, error="用户答案至少需要包含一个选项")
    )


class UserAnswerQueryRequest(Schema):
    # ID
    id = fields.Int(
        allow_none=True,
        required=False,
        validate=validate.Range(min=1, error="ID非法")
    )
    # 应用 id
    appId = fields.Int(
        allow_none=True,
        required=False,
    )
    # 应用类型（0-得分类，1-角色测评类）
    appType = fields.Int(
        required=False,
        allow_none=True,
        validate=validate.OneOf(
            [0, 1],
            error="appType数值非法！"
        )
    )
    # 评分策略（0-自定义，1-AI）
    scoringStrategy = fields.Int(
        required=False,
        allow_none=True,
        validate=validate.OneOf(
            [0, 1],
            error="scoringStrategy数值非法！"
        )
    )
    # 用户答案（JSON 数组）
    choices = fields.Str(
        required=False,
        allow_none=True,
    )
    # 评分结果 id
    resultId = fields.Int(
        required=False,
        allow_none=True,
    )
    # 结果名称，如物流师
    resultName = fields.Str(
        required=False,
        allow_none=True,
        validate=validate.Length(max=80, error="结果名称不得超过80个字符")
    )
    # 结果描述
    resultDesc = fields.Str(
        required=False,
        allow_none=True,
        validate=validate.Length(max=80, error="结果描述不得超过80个字符")
    )
    # 结果图标
    resultPicture = fields.Str(
        required=False,
        allow_none=True,
    )
    # 得分
    resultScore = fields.Int(
        required=False,
        allow_none=True,
    )
    # 用户 id
    userId = fields.Int(
        required=False,
        allow_none=True,
    )
    # 不需要的ID
    notId = fields.Int(
        allow_none=True,
        required=False,
        validate=validate.Range(min=1, error="ID非法")
    )
    # 搜索词
    searchText = fields.Str(
        required=False,
        allow_none=True,
    )
    # 分页大小
    pageSize = fields.Int(
        allow_none=True,
        validate=validate.Range(min=1)
    )
    # 当前页
    current = fields.Int(
        allow_none=True,
        validate=validate.Range(min=1)
    )
    # 排序字段
    sortField = fields.Str(
        allow_none=True,
        default='CreateTime'
    )
    # 排序顺序
    sortOrder = fields.Str(
        allow_none=True,
        default='asc'
    )
    # 是否删除
    isDelete = fields.Int(
        required=False,
        allow_none=True,
        validate=validate.OneOf(
            [0, 1],
            error="isDelete数值非法！"
        )
    )

    @pre_load
    def replace_none_with_default(self, data, **kwargs):
        defaults = {
            'pageSize': 10,
            'current': 1,
            'sortField': 'createTime',  # 与类定义保持一致
            'sortOrder': 'desc',
            'isDelete': 0,  # 设置为默认值0而不是None，因为验证要求是0或1
        }

        for field, default_value in defaults.items():
            if data.get(field) is None:
                data[field] = default_value
        return data
